package com.winter.common.config;

import com.github.xiaoymin.knife4j.spring.extension.OpenApiExtensionResolver;
import com.winter.common.constant.BaseMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.builders.ResponseBuilder;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.service.Response;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * Swagger 配置类
 *
 * @author zhangshuaiyin
 * @date 2021/5/31 21:58
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig {

    private final OpenApiExtensionResolver openApiExtensionResolver;

    /**
     * 通过该扩展给增强模式插件赋值，如自定义文档等
     *
     * @param openApiExtensionResolver Knife4j 扩展类
     */
    @Autowired
    public SwaggerConfig(OpenApiExtensionResolver openApiExtensionResolver) {
        this.openApiExtensionResolver = openApiExtensionResolver;
    }

    /**
     * 创建 zhang-admin API 应用
     * apiInfo() 增加API相关信息
     * 通过select()函数返回一个ApiSelectorBuilder实例,用来控制哪些接口暴露给Swagger来展现，
     * 本例采用指定扫描的包路径来定义指定要建立API的目录。
     *
     * @return Docket
     */
    @Bean
    public Docket adminApi() {
        //添加全局响应状态码
        List<Response> responseMessageList = new ArrayList<>();

        // 根据 BaseMessage 获取自定义响应码
        Arrays.stream(BaseMessage.values()).forEach(
                errorEnums -> responseMessageList.add(new ResponseBuilder()
                        .code(errorEnums.getCode())
                        .description(errorEnums.getMessage())
                        .build()));

        return new Docket(DocumentationType.OAS_30)
                // 添加全局响应状态码，可根据不同系统定义不同的响应码信息
                .globalResponses(HttpMethod.GET, responseMessageList)
                .globalResponses(HttpMethod.PUT, responseMessageList)
                .globalResponses(HttpMethod.POST, responseMessageList)
                .globalResponses(HttpMethod.DELETE, responseMessageList)
                .apiInfo(adminApiInfo())
                .select()
                // 标注@Api等注解的接口代码路径
                .apis(RequestHandlerSelectors.basePackage("com.winter.admin.controller"))
                .paths(PathSelectors.any())
                .build()
                // 构建扩展插件-自定义文档 group
                .extensions(openApiExtensionResolver.buildExtensions("doc-knife4j-1.0.0"))
                .groupName("Winter Admin 接口文档V1.0");
    }


    /**
     * 创建 zhang-admin API的基本信息（这些基本信息会展现在文档页面中）
     * 访问地址：http://项目实际地址/doc.html
     *
     * @return ApiInfo
     */
    private ApiInfo adminApiInfo() {
        return new ApiInfoBuilder()
                .title("Winter API")
                .description("Winter 后台管理接口文档")
                //服务条款网址
                .termsOfServiceUrl("https://gitee.com/rain-space/winter-platform")
                .version("1.0")
                .contact(new Contact("winter", "https://gitee.com/rain-space/winter-platform", "https://gitee.com/rain-space/winter-platform"))
                .build();
    }
}
